﻿import requests
import time
import base64
import random
import json
import hashlib
import redis_


with open('../config.py', 'r') as f:
    exec(f.read())

def get_time_stamp():
    return str(time.time())


def md5(src):
    m2 = hashlib.md5()
    m2.update(src.encode("utf8"))
    return m2.hexdigest()


def tobase64(str):
    encodestr = base64.b64encode(str.encode('utf-8'))
    return encodestr.decode()


class YITUYDN:
    def __init__(self, ip, port, username, password):
        self.ip = ip
        self.port = port
        self.username = username
        self.password = password

        self.session_id = redis_.RDB_get_session_id()
        self.cluster_id = redis_.RDB_get_cluster_id()

    def user_self(self):
        while True:
            try:
                self.getDBsession()
                url = 'http://' + self.ip + ':' + str(self.port) + '/resource_manager/user/self/global'
                r = requests.get(url, headers=self.headers())
                j = json.loads(r.text)
            except Exception as e:
                print(e)
                time.sleep(10)
                continue
            return j

    def login(self):
        while True:
            try:
                print(get_time_stamp(), 'login opreate!!!!!!!!!!!!!')
                url = 'http://' + self.ip + ':' + str(self.port) + '/website/face/v2/login'
                headers = {}
                data = {
                    "name": self.username,
                    "password": md5(self.password),
                    "cluster_id": "DEFAULT"
                }
                r = requests.post(url, headers=headers, json=data)
                j = json.loads(r.text)
            except Exception as e:
                print(e)
                time.sleep(10)
                continue
            return j

    def getDBsession(self):
        self.session_id = redis_.RDB_get_session_id()
        self.cluster_id = redis_.RDB_get_cluster_id()

    def headers(self):
        return {
            'Connection': 'close',
            'cookie': 'session_id=' + self.session_id + '; yt_cluster_id=' + self.cluster_id + '; cluster_id=' + self.cluster_id
        }

    def getCluster_id(self):
        while (True):
            self.getDBsession()
            if not self.cluster_id:
                print(get_time_stamp() + 'getCluster_id error')
                time.sleep(10)
                self.getDBsession()
                continue
            return self.cluster_id

    def getImgUrl(self, uri):
        arr = uri.split('@')
        uri = arr[0] + '@' + arr[1]
        return 'http://' + self.ip + ':' + str(
            self.port) + '/storage/v1/image/global?cluster_id=' + self.cluster_id + '&uri_base64=' + tobase64(uri)

    def getcamera(self):
        while (True):
            try:
                url = 'http://' + self.ip + ':' + str(
                    self.port) + '/face/v1/framework/face_video/camera/global?cluster_id=' + self.cluster_id
                r = requests.get(url, headers=self.headers())
                j = json.loads(r.text)
                if j and j['rtn'] != 0:
                    print(get_time_stamp() + 'getcamera error:' + str(j))
                    time.sleep(10)
                    self.getDBsession()
                    continue
            except Exception as e:
                print(e)
                time.sleep(10)
                self.getDBsession()
                continue
            return j

    def getrepository(self):
        while (True):
            try:
                url = 'http://' + self.ip + ':' + str(
                    self.port) + '/face/v1/framework/face_image/repository/global?cluster_id=' + self.cluster_id
                r = requests.get(url, headers=self.headers())
                j = json.loads(r.text)
                if j and j['rtn'] != 0:
                    print(get_time_stamp() + 'getrepository error:' + str(j))
                    time.sleep(10)
                    self.getDBsession()
                    continue
            except Exception as e:
                print(e)
                time.sleep(10)
                self.getDBsession()
                continue
            return j

    def repository_list(self, json):
        arr = []
        for results in json["results"]:
            j = {
                'repository_id': str(results['id']) + '@' + self.cluster_id,
                # "index_type": "yitu_171"
            }
            arr.append(j)
        return arr

    def camera_list(self, json):
        arr = []
        for camera in json["cameras"]:
            j = {
                'camera_id': str(camera['id']) + '@' + self.cluster_id
            }
            arr.append(j)
        return arr

    def camera_list_number(self, json):
        arr = []
        for camera in json["cameras"]:
            arr.append(camera['id'])
        return arr

    def ovo(self, feature_base64_1, feature_base64_2):
        url = 'http://' + self.ip + ':' + str(self.port) + '/face/v1/framework/face/verify'
        data = {
            "feature_base64_1": feature_base64_1,
            "feature_base64_2": feature_base64_2
        }
        r = requests.post(url, headers=self.headers(), json=data)
        j = json.loads(r.text)
        return j

    def ovn(self, camera_list, repository_list, image_content_base64, threshold, rec_gender, rec_age_range, count):
        for i in range(2):
            try:
                j = self._ovn(camera_list, repository_list, image_content_base64, threshold, rec_gender, rec_age_range,
                              count)
            except Exception as e:
                print(e)
                time.sleep(10)
                self.getDBsession()
                continue
            return j
        return {'rtn': -1}

    def _ovn(self, camera_list, repository_list, image_content_base64, threshold, rec_gender, rec_age_range, count):
        for i in range(2):
            # detect
            url = 'http://' + self.ip + ':' + str(self.port) + '/face/v1/framework/face/face_image/detection'
            data = {
                "options": {
                    "max_faces_allowed": -1
                },
                "image_content_base64": image_content_base64
            }
            try:
                r = requests.post(url, headers=self.headers(), json=data)
            except Exception as e:
                print(e)
                time.sleep(10)
                continue
            if r is None:
                return {'rtn': -2}
            try:
                j = json.loads(r.text)
            except Exception as e:
                print(e)
                time.sleep(10)
                self.getDBsession()
                continue
            if j and j['rtn'] != 0:
                print(get_time_stamp() + '_ovn detect error' + str(j))
                time.sleep(10)
                self.getDBsession()
                continue
            if len(j['results']) < 1:
                return {'rtn': -3}
            face_rect = j['results'][0]['face_rect']

            # ovn
            url = 'http://' + self.ip + ':' + str(self.port) + '/website/face/v2/retrieval/proxy/refactor'
            data = {
                "cluster_id": self.cluster_id,
                "fields": ["face_image_id",
                           "repository_id",
                           "timestamp",
                           "person_id",
                           "name",
                           # "gender",
                           # "nation",
                           "camera_id",
                           # "is_hit",
                           # "born_year",
                           # "comment",
                           "picture_uri",
                           "face_image_uri",
                           "face_rect",
                           # "multi_frame_face_image_uris",
                           # "multi_frame_picture_uris",
                           # "multi_frame_face_rects",
                           "rec_glasses",
                           "rec_fringe",
                           "rec_uygur",
                           "rec_gender",
                           "rec_age",
                           "rec_age_range",
                           "similarity",
                           "quality",
                           # "annotation",
                           # "case_number",
                           # "remark",
                           "yitu_171_feature_base64"],
                "condition": {},
                "query_meta": {},
                "order": {
                    "similarity": -1
                },
                "start": 0,
                "limit": count,
                "retrieval": {
                    "image_content_base64": image_content_base64,
                    "face_rect": face_rect,
                    "threshold": threshold
                }
            }
            if repository_list is not None:
                data['retrieval']['repository_list'] = repository_list
            if camera_list is not None:
                data['retrieval']['camera_list'] = camera_list
            data['condition']['rec_age_range'] = {"$ne": 0}

            try:
                r = requests.post(url, headers=self.headers(), json=data)
            except Exception as e:
                print(e)
                time.sleep(10)
                continue

            if r is None:
                return {'rtn': -1}
            try:
                j = json.loads(r.text)
            except Exception as e:
                print(e)
                time.sleep(10)
                self.getDBsession()
                continue
            if j and j['rtn'] != 0:
                print(get_time_stamp() + '_ovn error' + str(j))
                time.sleep(10)
                self.getDBsession()
                continue
            return j


if __name__ == '__main__':
    yituydn = YITUYDN(yituinfo['ip'], yituinfo['port'], yituinfo['username'], yituinfo['password'])
    while True:
        j = yituydn.user_self()
        if j and j['rtn'] != 0:
            print(get_time_stamp(), 'session need flush!')
            j = yituydn.login()
            if j and j['rtn'] == 0:
                print(get_time_stamp(), 'session flush ok', j['session_id'], j['cluster_id'])
                redis_.RDB_set_session_id(j['session_id'])
                redis_.RDB_set_cluster_id(j['cluster_id'])
            else:
                print(get_time_stamp(), 'session flush err', j)
        else:
            print(get_time_stamp(), 'session not need flush')
        time.sleep(5)
